---
title: 分布式ID
---

在分布式系统中，往往需要对大量的数据和消息进行唯一标识。比如数据分库分表后需要有一个唯一 ID 来标识一条数据和消息。

## 传统方案

* 时间戳
* UUID

## 分布式ID特点

* 全局唯一
* 高并发
* 高可用

:::tip
相同应用在多台服务器（docker容器），ID唯一。
:::

## 实现方案优缺点

### UUID

* 空间占用过多
* 不能生成递增有序的的数字，索引效率下降（最致命的缺点）

### 数据库主键自增

* 并发性能不高，受限于数据库性能
* 分库分表时，需要改造
* 自增： 数据量泄露

### Redis 自增

* 数据丢失
* 自增： 数据量泄露

### 雪花算法（snowflake）

最大的优点是不依赖于外部的组件，缺点是因为算法里用到了时间戳，所以会有时钟回拨问题。

## 可用方案总结

最佳模式有两个，一个是号段模式，一个是雪花算法。

### 号段模式

号段模式还是依赖数据库的，但它又不是数据库主键自增的模式。
相比于主键自增模式，性能显著提高。

### 雪花算法（snowflake）

**时间戳（毫秒）+ 机器序号 + 自增数**

![image-20230429043541635](C:\Users\21129\AppData\Roaming\Typora\typora-user-images\image-20230429043541635.png)

10 位工作进程位我们通常将其划分为 5+5（区域(机房)+服务器标识），序列号位就是自增。

时间范围： `2^41/(365*24*60*60*1000)≈69年`

工作进程数量： `2^10`=1024

序列号数量：`2^12=4096`

:::tip

三个组成部分的位数可以根据自己公司的场景进行定制，比如百度雪花算法 时间范围时候的单位就是 秒。

:::





## 美团（Leaf）

程序在运行时，会上报服务器标识到 ZK，ZK 进行存储。

